package com.weilele.mvvm.utils.download

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.graphics.drawable.BitmapDrawable
import android.media.RingtoneManager
import android.os.Build
import android.os.Environment
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import com.weilele.mvvm.utils.activity.getResString

/**
 * 下载发送通知的工具类
 */
open class DownFileWithNotification : DownListener() {
    //下载apk的任务管理
    private var downloadHelper: DownloadHelper? = null

    //通知id
    private var NOTIFICATION_ID = 0

    //上下文，全局的application
    private var context: Context? = null

    //通知栏构建器
    private var build: NotificationCompat.Builder? = null

    //通知栏对象
    private lateinit var notificationManager: NotificationManager

    //点击通知栏
    private var clickIntent: PendingIntent? = null

    //点击取消按钮
    private var cancelIntent: PendingIntent? = null

    /**
     * 通知栏标题
     */
    var notifyTitle = "正在下载新版本..."

    /**
     * 通知栏内容
     */
    var notifyContent = "下载的应用名"

    /**
     * 8.0以上 渠道名标题
     */
    var notifyChannelTitle = notifyContent

    /**
     * logo，一般为被下载的app图标
     */
    var iconRes = android.R.drawable.stat_sys_download_done

    /**
     * 下载完成监听
     */
    var downloadCompleteListener: Function1<DownloadBean?, Unit>? = null

    /**
     * 开始下载apk
     */
    fun startDown(
            context: Context?,
            url: String,
            notificationId: Int,
            clickIntent: PendingIntent?,
            cancelIntent: PendingIntent?,
            fileName: String,
            pathType: String = Environment.DIRECTORY_DOWNLOADS,
            midPath: String? = null,
            isDownWhenExist: Boolean = false
    ): Boolean/*返回值：是否创建新的任务*/ {
        return if (downloadHelper == null) {
            this.context = context
            NOTIFICATION_ID = notificationId
            this.clickIntent = clickIntent
            this.cancelIntent = cancelIntent
            downloadHelper = DownloadHelper().apply {
                setOverlayFile(isDownWhenExist)
                setPathType(pathType, midPath)
                start(url, fileName, this@DownFileWithNotification)
                notificationManager =
                        context!!.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                build = sendNotify()
            }
            true
        } else {
            false
        }
    }

    /**
     * 下载完成回调
     */
    override fun onComplete(result: DownloadBean?) {
        super.onComplete(result)
        stopDown()
        downloadCompleteListener?.invoke(result)
    }

    override fun onError(error: Throwable) {
        super.onError(error)
        stopDown()
    }

    override fun onCancelled() {
        super.onCancelled()
        stopDown()
    }

    override fun onCancelled(result: DownloadBean?) {
        super.onCancelled(result)
        stopDown()
    }

    /**
     * 结束下载
     */
    fun stopDown() {
        if (downloadHelper != null) {
            downloadHelper?.cancel()
            downloadHelper = null
            clearNotify(NOTIFICATION_ID)
            context = null
            clickIntent = null
            cancelIntent = null
        }
    }

    /**
     * 在子线程接受进度回调
     * 主线程频繁更新进度会导致卡死
     */
    override fun onProgressUpdateInIoThread(downloadSize: Long, totalSize: Long, progress: Long) {
        super.onProgressUpdateInIoThread(downloadSize, totalSize, progress)
        updateNotify(progress)
    }

    /**
     * 更新进度
     */
    private fun updateNotify(progress: Long) {
        build?.let {
            it.setProgress(100, progress.toInt(), false)
            notificationManager.notify(javaClass.simpleName, NOTIFICATION_ID, it.build())
        }
    }

    /**
     * 发送初始进度
     */
    private fun sendNotify(): NotificationCompat.Builder? {
        val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val notificationBuilder = NotificationCompat.Builder(context!!, NOTIFICATION_ID.toString())
                .setSmallIcon(android.R.drawable.stat_sys_download)
                .setContentTitle(notifyTitle)
                //使用默认的声音、振动、闪光
                .setDefaults(Notification.DEFAULT_ALL)
                .setContentText(notifyContent)
                .setLargeIcon((ContextCompat.getDrawable(context!!, iconRes) as BitmapDrawable).bitmap)
                .setAutoCancel(false)
                .setProgress(100, 0, true)
                .setSound(defaultSoundUri)
                .setOngoing(true)
                .setContentIntent(clickIntent)
                .setShowWhen(true)
                .setTicker(notifyTitle)//在状态栏短暂显示的文字
        cancelIntent?.let {
            notificationBuilder.addAction(
                    android.R.drawable.ic_menu_close_clear_cancel,
                    getResString(android.R.string.cancel),
                    it
            )
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                    NOTIFICATION_ID.toString(),
                    notifyChannelTitle,
                    NotificationManager.IMPORTANCE_LOW
            )
            notificationManager.createNotificationChannel(channel)
        }
        notificationManager.notify(
                javaClass.simpleName,
                NOTIFICATION_ID,
                notificationBuilder.build()
        )
        return notificationBuilder
    }

    /**
     * 清除通知
     */
    private fun clearNotify(id: Int) {
        notificationManager.cancel(id)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationManager.deleteNotificationChannel(id.toString())
        }
    }
}